'use strict';
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _GridLayer_id, _GridLayer_grid, _GridLayer_legend, _GridLayer_options, _GridLayer_models, _GridLayer_maskInfo, _GridLayer_drawModel, _GridLayer_gridVao, _GridLayer_elementType, _GridLayer_vertexCount, _GridLayer_gridTexture;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GridLayer = void 0;
//import { createTextureStorage2D, bindTexture2D, createShader } from './webgl_util';
//import { getMaskInfo } from "./mask/index";
// 程序对象（Program Object）是一个包含顶点着色器和片段着色器的对象，它们在GPU上执行以渲染图形。
// 属性是与顶点数据相关的变量。每个顶点可以有不同的属性值，例如位置、颜色、纹理坐标等。
// 属性通常用于将顶点数据从CPU传递到GPU。
// 在着色器代码中，属性变量使用attribute关键字声明。
// 统一变量是与片段着色器相关的变量。它们通常用于控制着色器的行为，
// 它们用于传递在整个渲染过程中保持不变的数据，例如颜色、透明度、光照等。
// function createModel(gl, vertexSource, fragmentSource) {
//     // 创建了一个WebGL程序对象,该对象是着色器链接后的产物，用于在GPU上执行着色器代码。
//     const program = gl.createProgram();
//     // 创建顶点着色器
//     const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource);
//     // 片段着色器
//     const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
//     // 将着色器附加到程序对象
//     gl.attachShader(program, vertexShader);
//     gl.attachShader(program, fragmentShader);
//     // 链接程序对象
//     gl.linkProgram(program);
//     if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
//         throw new Error(gl.getProgramInfoLog(program));
//     }
//     // 创建包装对象
//     const wrapper = { program };
//     // 获取程序对象中的所有活动属性，并将它们的名称和位置存储在包装对象中。
//     const numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
//     for (let i = 0; i < numAttributes; i++) {
//         const attribute = gl.getActiveAttrib(program, i);
//         wrapper[attribute.name] = gl.getAttribLocation(program, attribute.name);
//     }
//     // 获取程序对象中的所有活动统一变量，并将它们的名称和位置存储在包装对象中。
//     const numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
//     for (let i = 0; i < numUniforms; i++) {
//         const uniform = gl.getActiveUniform(program, i);
//         wrapper[uniform.name] = gl.getUniformLocation(program, uniform.name);
//     }
//     // 返回包含程序对象及其属性和统一变量位置的包装对象。
//     return wrapper;
// }
// 通过生成随机的十六进制字符串并将其组合成标准的UUID格式，实现了生成UUID的功能。
// UUID通常用于唯一标识信息，确保在分布式系统中不会发生冲突。
// function uuid() {
//     function s4() {
//         // eslint-disable-next-line no-bitwise
//         return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
//     }
//     return (s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4());
// }
// eslint-disable-next-line no-unused-vars
var GridLayer = /** @class */ (function () {
    // 始化 GridLayer 类的实例
    function GridLayer(grid, legend, options) {
        _GridLayer_id.set(this, void 0); //层的唯一标识符。
        _GridLayer_grid.set(this, void 0); //网格数据。
        _GridLayer_legend.set(this, void 0); //颜色图例，用于将数值映射到颜色。
        _GridLayer_options.set(this, void 0); //层的配置选项。
        _GridLayer_models.set(this, void 0); //存储模型的对象。
        _GridLayer_maskInfo.set(this, void 0); //掩膜信息。
        _GridLayer_drawModel.set(this, void 0); //绘制模型。
        _GridLayer_gridVao.set(this, void 0); //网格顶点数组对象。
        _GridLayer_elementType.set(this, void 0); // 元素类型。
        _GridLayer_vertexCount.set(this, void 0); //顶点数量。
        _GridLayer_gridTexture.set(this, void 0); //网格纹理。
        __classPrivateFieldSet(this, _GridLayer_id, (options.id) ? options.id : uuid(), "f");
        __classPrivateFieldSet(this, _GridLayer_grid, grid, "f");
        __classPrivateFieldSet(this, _GridLayer_legend, legend, "f");
        __classPrivateFieldSet(this, _GridLayer_options, options, "f");
        __classPrivateFieldSet(this, _GridLayer_models, {}, "f");
    }
    Object.defineProperty(GridLayer.prototype, "id", {
        //提供对 id, type, renderingMode, mask, opacity 等属性的访问和修改。
        // set mask 和 set opacity 方法在修改属性时会触发地图的重绘。
        get: function () {
            return __classPrivateFieldGet(this, _GridLayer_id, "f");
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(GridLayer.prototype, "type", {
        get: function () {
            return 'custom';
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(GridLayer.prototype, "renderingMode", {
        get: function () {
            return '2d';
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(GridLayer.prototype, "mask", {
        get: function () {
            return __classPrivateFieldGet(this, _GridLayer_options, "f").mask;
        },
        // 重置裁剪区域
        set: function (mask) {
            __classPrivateFieldGet(this, _GridLayer_options, "f").mask = mask;
            var gl = this.gl;
            if (mask) {
                __classPrivateFieldSet(this, _GridLayer_maskInfo, getMaskInfo(this.mask, gl), "f");
                __classPrivateFieldGet(this, _GridLayer_models, "f")['mask'] = __classPrivateFieldGet(this, _GridLayer_maskInfo, "f").model;
            }
            else {
                var model = __classPrivateFieldGet(this, _GridLayer_models, "f")['mask'];
                if (model) {
                    model.destroy();
                    delete __classPrivateFieldGet(this, _GridLayer_models, "f")['mask'];
                    __classPrivateFieldSet(this, _GridLayer_maskInfo, null, "f");
                }
            }
            this.map.triggerRepaint();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(GridLayer.prototype, "opacity", {
        get: function () {
            return __classPrivateFieldGet(this, _GridLayer_options, "f").opacity;
        },
        set: function (o) {
            __classPrivateFieldGet(this, _GridLayer_options, "f").opacity = o;
            if (this.gl) {
                var model = __classPrivateFieldGet(this, _GridLayer_drawModel, "f");
                this.gl.useProgram(model.program);
                // 绑定计算所需地理变量
                this.gl.uniform1f(model.u_opacity, this.opacity);
                this.map.triggerRepaint();
            }
        },
        enumerable: false,
        configurable: true
    });
    // loader 方法用于加载新的网格数据，并更新相关的 WebGL 统一变量和纹理。
    GridLayer.prototype.loader = function (grid) {
        __classPrivateFieldSet(this, _GridLayer_grid, grid, "f");
        if (this.gl) {
            var gl = this.gl;
            var model = __classPrivateFieldGet(this, _GridLayer_drawModel, "f");
            gl.useProgram(model.program);
            // 绑定计算所需地理变量
            gl.uniform2fv(model.start, [grid.startX, grid.startY]);
            gl.uniform2fv(model.end, [grid.endX, grid.endY]);
            __classPrivateFieldSet(this, _GridLayer_gridTexture, this.gridFloatTexture(grid), "f");
            this.map.triggerRepaint();
        }
    };
    // setBreakColorUniform 方法将颜色图例转换为 WebGL 统一变量。
    GridLayer.prototype.setBreakColorUniform = function (gl, program, normalizationColorMap) {
        // 真实值生成的颜色渐变区间
        var stops = [], colors = [];
        // 先提取key
        for (var _i = 0, normalizationColorMap_1 = normalizationColorMap; _i < normalizationColorMap_1.length; _i++) {
            var key = normalizationColorMap_1[_i][0];
            stops.push(key);
        }
        // key根据sort从小到大排序
        stops = stops.sort(function (a, b) { return +(a) - +(b); });
        for (var _a = 0, stops_1 = stops; _a < stops_1.length; _a++) {
            var key = stops_1[_a];
            var value = normalizationColorMap.get(key);
            var alpha = void 0;
            if (value[3] !== undefined)
                alpha = value[3];
            else
                alpha = 0.75;
            colors.push(value[0] / 255.0);
            colors.push(value[1] / 255.0);
            colors.push(value[2] / 255.0);
            colors.push(alpha);
        }
        // 传入数组
        gl.useProgram(program);
        var stopsLocation = gl.getUniformLocation(program, 'u_stops');
        var colorsLocation = gl.getUniformLocation(program, 'u_colors');
        gl.uniform1fv(stopsLocation, stops);
        gl.uniform4fv(colorsLocation, colors);
    };
    //创建并编译顶点和片段着色器。
    GridLayer.prototype._createModel = function () {
        var vs = "#version 300 es\n        layout(location=0) in vec2 a_position;\n        uniform mat4 u_worldViewProjection;\n        out vec2 v_position;\n       \n        void main() {\n            gl_Position = u_worldViewProjection*vec4(a_position,0.0, 1.0);\n            v_position = a_position;\n        }";
        var size = __classPrivateFieldGet(this, _GridLayer_legend, "f").size;
        var fs = "#version 300 es\n        precision highp float;\n        #define M_PI 3.141592653589793 \n\n        uniform vec2 start;\n        uniform vec2 end;\n      \n        uniform float u_stops[".concat(size, "];\n        uniform vec4 u_colors[").concat(size, "];\n\n        uniform float u_opacity;\n\n        uniform sampler2D u_gridTexture;\n      \n        in vec2 v_position;\n        out vec4 outColor;\n\n        // \u58A8\u5361\u6258\u8F6C\u7ECF\u7EAC\u5EA6\n        vec2 mkt2lonlat(vec2 mkt){\n            float lon = mkt.x * 360.0 - 180.0;\n            float y2 = 180.0 - mkt.y * 360.0;\n            float lat =  360.0 / M_PI * atan(exp(y2 * M_PI / 180.0)) - 90.0;\n            return vec2(lon,lat);\n        }\n    \n        void main() {\n            int lastIndex = ").concat(size, " - 1;\n\n\n            // \u628A\u58A8\u5361\u6258\u5750\u6807\u8F6C\u6362\u6210\u7ECF\u7EAC\u5EA6\n            vec2 lonlat = mkt2lonlat(v_position);\n            vec2 v_uv = (lonlat - start)/(end - start);\n            float val = texture(u_gridTexture, v_uv).r;\n\n            // \u5C06\u6D6E\u70B9\u578B\u8F6C0-1\u5750\u6807\u7CFB\n            // \u5927\u4E8E\u5927\u503C\n            if(val>=u_stops[lastIndex])\n                outColor = vec4(u_colors[lastIndex].rgb*u_colors[lastIndex].a*u_opacity,u_colors[lastIndex].a*u_opacity);\n            // \u5C0F\u4E8E\u5C0F\u503C\n            else if(val<u_stops[0])\n                outColor = vec4(u_colors[0].rgb*u_colors[0].a*u_opacity,u_colors[0].a*u_opacity);\n            else {\n                for(int i=0;i<lastIndex;i++){\n                    if(val>=u_stops[i]&&val<u_stops[i+1]){\n                        // \u9884\u4E58\u963F\u5C14\u6CD5\n                        outColor = vec4(u_colors[i].rgb*u_colors[i].a*u_opacity,u_colors[i].a*u_opacity);\n                        break;\n                    } \n                }\n            }\n        }");
        __classPrivateFieldSet(this, _GridLayer_drawModel, createModel(this.gl, vs, fs), "f");
    };
    // 创建顶点数组对象（VAO）并绑定顶点数据。
    GridLayer.prototype._createVao = function () {
        var gl = this.gl;
        var minx = __classPrivateFieldGet(this, _GridLayer_grid, "f").startX;
        var miny = Math.min(__classPrivateFieldGet(this, _GridLayer_grid, "f").startY, __classPrivateFieldGet(this, _GridLayer_grid, "f").endY);
        var maxx = __classPrivateFieldGet(this, _GridLayer_grid, "f").endX;
        var maxy = Math.max(__classPrivateFieldGet(this, _GridLayer_grid, "f").startY, __classPrivateFieldGet(this, _GridLayer_grid, "f").endY);
        var coordinates = [
            minx, miny,
            minx, maxy,
            maxx, maxy,
            maxx, miny,
        ];
        var pos = new Float32Array(coordinates.length);
        for (var i = 0; i < coordinates.length; i = i + 2) {
            // eslint-disable-next-line no-undef
            var coors = mapboxgl.MercatorCoordinate.fromLngLat({ lng: coordinates[i], lat: coordinates[i + 1] }, 0);
            pos[i] = coors.x;
            pos[i + 1] = coors.y;
        }
        var indices = [
            1, 0, 3,
            1, 3, 2,
        ];
        // //////////////////////////////
        //  SET UP 顶点
        // //////////////////////////////
        __classPrivateFieldSet(this, _GridLayer_gridVao, gl.createVertexArray(), "f");
        gl.bindVertexArray(__classPrivateFieldGet(this, _GridLayer_gridVao, "f"));
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, pos, gl.STATIC_DRAW);
        gl.enableVertexAttribArray(0);
        gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
        var indicesBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices), gl.STATIC_DRAW);
        __classPrivateFieldSet(this, _GridLayer_elementType, gl.UNSIGNED_BYTE, "f");
        __classPrivateFieldSet(this, _GridLayer_vertexCount, indices.length, "f");
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
        gl.bindVertexArray(null);
    };
    // 设置 WebGL 统一变量。
    GridLayer.prototype._createUniform = function () {
        var gl = this.gl;
        var grid = __classPrivateFieldGet(this, _GridLayer_grid, "f");
        var gridModel = __classPrivateFieldGet(this, _GridLayer_drawModel, "f");
        gl.useProgram(gridModel.program);
        // 绑定计算所需地理变量
        gl.uniform2fv(gridModel.start, [grid.startX, grid.startY]);
        gl.uniform2fv(gridModel.end, [grid.endX, grid.endY]);
        gl.uniform1f(gridModel.u_opacity, this.opacity);
        // 绑定数据纹理
        this.setBreakColorUniform(gl, gridModel.program, __classPrivateFieldGet(this, _GridLayer_legend, "f"));
        __classPrivateFieldSet(this, _GridLayer_gridTexture, this.gridFloatTexture(grid), "f");
    };
    // 创建网格浮点型纹理。
    GridLayer.prototype.gridFloatTexture = function (grid) {
        var _a, _b;
        var gl = this.gl;
        var texture = createTextureStorage2D(gl, {
            width: grid.width,
            height: grid.height,
            data: grid.grids,
            internalFormat: gl.RED, //webgl使用格式
            srcFormat: gl.R32F, //输入数据格式 
            type: gl.FLOAT,
            //声明该设置，否则会报错 Texture format does not support mipmap generation
            pixelStore: (_a = {},
                _a[gl.UNPACK_ALIGNMENT] = 1,
                _a[gl.UNPACK_FLIP_Y_WEBGL] = 0,
                _a),
            parameters: (_b = {},
                _b[gl.TEXTURE_MAG_FILTER] = gl.LINEAR,
                _b[gl.TEXTURE_MIN_FILTER] = gl.LINEAR,
                _b[gl.TEXTURE_WRAP_S] = gl.CLAMP_TO_EDGE,
                _b[gl.TEXTURE_WRAP_T] = gl.CLAMP_TO_EDGE,
                _b),
            levels: 1
        });
        return texture;
    };
    // 初始化方法，创建 WebGL 资源。
    GridLayer.prototype.initialize = function () {
        if (!this.map) {
            return;
        }
        this._createModel();
        this._createVao();
        this._createUniform();
    };
    //网格层被添加到地图时调用，初始化相关设置。
    GridLayer.prototype.onAdd = function (map, gl) {
        this.map = map;
        this.gl = gl;
        // 为了支持浮点型纹理过滤
        if (!gl.getExtension('OES_texture_float_linear')) {
            console.error('OES_texture_float_linear not available');
        }
        this.mask = __classPrivateFieldGet(this, _GridLayer_options, "f").mask;
        this.initialize();
    };
    //负责在每一帧中渲染网格层。
    GridLayer.prototype.render = function (gl, matrix) {
        // 绘制掩膜
        if (this.mask)
            __classPrivateFieldGet(this, _GridLayer_maskInfo, "f").draw(gl, matrix);
        var model = __classPrivateFieldGet(this, _GridLayer_drawModel, "f");
        gl.useProgram(model.program);
        // 设置unifrom
        gl.uniformMatrix4fv(model.u_worldViewProjection, false, matrix);
        bindTexture2D(gl, __classPrivateFieldGet(this, _GridLayer_gridTexture, "f"), 11);
        gl.uniform1i(model.u_gridTexture, 11);
        // 绑定顶点vao
        gl.bindVertexArray(__classPrivateFieldGet(this, _GridLayer_gridVao, "f"));
        gl.drawElements(gl.TRIANGLES, __classPrivateFieldGet(this, _GridLayer_vertexCount, "f"), __classPrivateFieldGet(this, _GridLayer_elementType, "f"), 0);
        if (this.mask) {
            var context = this.map.painter.context;
            this.map.painter.currentStencilSource = undefined;
            context.setStencilMode(this.map.painter.stencilClearMode);
            gl.disable(gl.STENCIL_TEST);
        }
        gl.bindVertexArray(null);
    };
    return GridLayer;
}());
exports.GridLayer = GridLayer;
_GridLayer_id = new WeakMap(), _GridLayer_grid = new WeakMap(), _GridLayer_legend = new WeakMap(), _GridLayer_options = new WeakMap(), _GridLayer_models = new WeakMap(), _GridLayer_maskInfo = new WeakMap(), _GridLayer_drawModel = new WeakMap(), _GridLayer_gridVao = new WeakMap(), _GridLayer_elementType = new WeakMap(), _GridLayer_vertexCount = new WeakMap(), _GridLayer_gridTexture = new WeakMap();
